﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NeurOthello.Logic
{
    class BitboardHash
    {
        private static int[,] hashVals = new int[64, 2];        
        private int boardHash, rotatedHash90, rotatedHash180, rotatedHash270;
        public BitboardHash Rotated90 { get { return new BitboardHash(rotatedHash90); } }
        public BitboardHash Rotated180 { get { return new BitboardHash(rotatedHash180); } }
        public BitboardHash Rotated270 { get { return new BitboardHash(rotatedHash270); } }
        private bool hashInnitiated = false;

        public BitboardHash()
        {
            if (!hashInnitiated)
            {
                InnitiateHashValues();
                hashInnitiated = true;
            }
        }

        public BitboardHash(BitboardHash hash)
        {
            boardHash = hash.boardHash;
        }

        public BitboardHash(int hash)
        {
            boardHash = hash;
        }

        public void UpdateHash(int sqrN, int playerId)
        {
            boardHash ^= hashVals[sqrN, playerId - 1];
            rotatedHash90 ^= hashVals[Bitboard.BitScanFwd(Bitboard.Rotate90(1UL << sqrN)), playerId-1];
            rotatedHash180 ^= hashVals[Bitboard.BitScanFwd(Bitboard.Rotate180(1UL << sqrN)), playerId - 1];
            rotatedHash270 ^= hashVals[Bitboard.BitScanFwd(Bitboard.Rotate270(1UL << sqrN)), playerId - 1];
        }

        private void InnitiateHashValues()
        {
            Random rand = new Random();
            List<int> uniqueRandInts = new List<int>();
            int newI;
          /*  foreach (int i in hashVals)
            {
                //while (
                i = rand.Next();
               
            }*/
            for (int i = 0; i < 128; i++)
            {
                while (uniqueRandInts.Contains(newI = rand.Next())) ;
                uniqueRandInts.Add(newI);
            }
            for (int i = 0; i < 64; i++)
            {
                hashVals[i, 0] = uniqueRandInts[i];
                hashVals[i, 1] = uniqueRandInts[64 + i];
            }

            boardHash = 0 ^ hashVals[27, 1] ^ hashVals[28, 0] ^ hashVals[36, 1] ^ hashVals[35, 0];
            rotatedHash180 = boardHash;

            rotatedHash90 = 0 ^ hashVals[27, 0] ^ hashVals[28, 1] ^ hashVals[36, 0] ^ hashVals[35, 1];
            rotatedHash270 = rotatedHash90;
        }

        public override int GetHashCode()
        {
            return boardHash;
        }

        public override bool Equals(object obj)
        {
            BitboardHash comp = obj as BitboardHash;
            return boardHash == comp.boardHash;
        }

    }
}
